;;
;; Windows DDK build environment
;; Base on DDK6000 setenv.bat
;;
;; ***************** Notice **********************
;; Change basedir to your DDK directory before use
;; ***********************************************
;; Add (require 'wwn) in your .emacs file.
;; Command : M-x wwn-setenv 
;; F5 for build
;; You need close *compilation* buffer before switch build environment
;; Contact : mr.madtrapper@gmail.com
;; --------------------------------------
;; Version 0.7
;; Add BASEDIR and OBJECT_ROOT, format source code
;; Aug 27, 2009
;; --------------------------------------
;; Version 0.6
;;	Add DDK build menu item
;;	Use M-x ddk-mode to switch mode
;; --------------------------------------
;;

(defvar basedir "C:\\WinDDK\\6000")

(defun wwn-setenv (OS CPU VER)
  (interactive "sOS:w2k, WXP, WNet, Wlh? \nsCPU:AMD64, I386, IA64? \nschk or free? ")

  (message "Set driver build envarment: %s, %s, %s" OS CPU VER)

  ;; reasonable defaults
  (setenv  "_FreeBuild" "true")
  (setenv  "_IA64bit" "false")
  (setenv  "_AMD64bit" "false")
  (setenv  "_HalBuild" "false")
  (setenv  "_BscMake" "FALSE")
  (setenv  "_VersionedHeaders" "TRUE")
  (setenv  "_LatestOsTarget" "wlh")
  (setenv  "RAZZLETOOLPATH" (concat basedir "\\bin"))

  (defvar path "C:\\WinDDK\\6000;")
  (setenv "BASEDIR" basedir)
  (setenv "OBJECT_ROOT" basedir)

;;-------------------  OS ---------------------------------
  (if (string-equal
	   OS "w2k")
	  (progn
		(setenv "_title" "Windows 2000")
		(setenv "W2K" "_w2k")
		(setenv " _ddkspec" "w2K")
		(setenv "_NT_TARGET_VERSION" "0x500")
		(setenv "WIN2K_DDKBUILD" "1")
		(setenv "NO_SAFESEH" "1")
		(setenv "COFFBASE_TXT_FILE" (concat basedir "\\bin\\w2k\\coffbase.txt"))
		(setenv "DDK_TARGET_OS" "Win2K")
		)
	)

  (if (string-equal OS "WXP")
	  (progn
		(setenv "_title" "Windows XP")
		(setenv "DDK_TARGET_OS" "WinXp")
		(setenv "_ddkspec" "wxp")
		(setenv "_NT_TARGET_VERSION" "0x501")
		)
	)

  (if (string-equal OS "WNet")
	  (progn
		(setenv "_title" "Windows Server 2003")
		(setenv "DDK_TARGET_OS" "WinNET")
		(setenv "_ddkspec" "wnet")
		(setenv "_NT_TARGET_VERSION" "0x502")
		(setenv "BUFFER_OVERFLOW_CHECKS" "1")
		)
	)

  (if (string-equal OS "Wlh")
	  (progn
		(setenv "DDK_TARGET_OS" "WinLH")
		(setenv "_ddkspec" "wlh")
		(setenv "_NT_TARGET_VERSION" "0x600")
		(setenv "BUFFER_OVERFLOW_CHECKS" "1") ;;FIXME
		)
	)

;;CPU
;;--------------------- AMD64 -------------------------------
  (if (string-equal CPU "AMD64")
	  (progn
		(setenv "_title" "x64")
		(setenv "_AMD64bit" "true")
		(setenv "CPU" "AMD64")
		(setenv "BUILD_DEFAULT_TARGETS" "-amd64")
		(setenv "_BUILDARCH" "AMD64")
		(setenv "AMD64" "1")
		(setq path (concat basedir "\\bin\\x86;"
						   basedir "\\bin\\x86\\amd64;"
						   basedir "\\bin\\SelfSign;"
						   basedir "\\bin\\tools\\sdv;"
						   basedir "\\tools\\pfd\\bin\\bin\\x86_AMD64;"
						   path))
		;; (setenv "BUILD_OPTIONS" "%BUILD_OPTIONS% ~imca ~toastpkg")
		
		(setenv "SDV" (concat basedir "\\tools\\sdv"))
		(setq path (concat basedir (concat (getenv "SDV") "\\bin;") path))
		)
	)
;;-----------------i386--------------------------------
  (if (string-equal CPU "I386")
	  (progn
		;;(setenv "_IA32bit" "true")  FIXME
		(setenv "CPU" "x86")
		(setq path (concat basedir "\\bin;"
						   basedir "\\bin\\x86;"
						   basedir "\\bin\\x86\\x86;"
						   basedir "\\bin\\SelfSign;"
						   basedir "\\bin\\tools\\pfd\\bin\\bin\\x86;"
						   path))

		(setenv "BUILD_DEFAULT_TARGETS" "-386")
		(setenv "_BUILDARCH" "x86")
		(setq path (concat basedir "\\tools\\pfd\\bin\\bin\\x86;" path))

		(defvar SDV "")
		(setq SDV (concat basedir "\\tools\\sdv"))
		(setq path (concat basedir (concat SDV "\\bin;") path))
		(setenv "_title" "x86")
		)
	)
;;----------------IA64------------------------------------
  (if (string-equal CPU "IA64")
	  (progn
		(setenv "_IA64bit" "true")
		(setenv "CPU" "IA64")
		(setenv "BUILD_DEFAULT_TARGETS" "-ia64")
		(setenv "_BUILDARCH" "IA64")
		(setenv "IA64" "1")

		(setq path (concat basedir "\\bin\\x86\\ia64;"
						   basedir "\\bin\\x86;"					 
						   basedir "\\bin\\SelfSign;"
						   path))
		)
	)

;;--------------------- version ---------------------------
(if (string-equal
	 VER "free")
	(progn
	  (setenv "_FreeBuild" "true")
	  (setenv "BUILD_ALT_DIR" (concat "fre_" (getenv "_ddkspec") "_" (getenv "_BUILDARCH")))
	  (setenv "NTDBGFILES" "1")
	  (setenv "NTDEBUG" "ntsdnodbg")
	  (setenv "NTDEBUGTYPE" "windbg")
	  (setenv "MSC_OPTIMIZATION" "")
	  (setenv "DDKBUILDENV" "fre")  
	  )
  )

(if (string-equal
	 VER "chk")
	(progn	
	  (setenv "_FreeBuild" "false")
	  (setenv "BUILD_ALT_DIR" (concat "chk_" (getenv "_ddkspec") "_" (getenv "_BUILDARCH")))

	  (setenv "NTDBGFILES" "1")
	  (setenv "NTDEBUG" "ntsd")
	  (setenv "NTDEBUGTYPE" "both")
	  (setenv "MSC_OPTIMIZATION" "/Od /Oi ")
	  (setenv "DDKBUILDENV" "chk")
	  (setenv "DEPRECATE_DDK_FUNCTIONS" "1")
	  (setenv "BUILD_ALLOW_COMPILER_WARNINGS" "1")  
	  )
  )

;;Get started
(setenv "_NT_TOOLS_VERSION" "0x700")
(setenv "COFFBASE_TXT_FILE" (concat basedir "\\bin\\coffbase.txt"))

;;Begin common section
(setenv "LANGUAGE_NEUTRAL" "0")
(setenv "PROJECT_ROOT" (concat basedir "\\src"))
(setenv "PUBLIC_ROOT" basedir)
(setenv "Lib" (concat basedir "\\lib"))
(setenv "Include" (concat basedir "\\inc\\api"))
(setenv "WPP_CONFIG_PATH" (concat basedir "\\bin\\wppconfig"))
(setenv "NTMAKEENV" (concat basedir "\\bin"))
(setenv "BUILD_MAKE_PROGRAM" "nmake.exe")
(setenv "BUILD_DEFAULT" "-ei -nmake -i")
(setenv "BUILD_MULTIPROCESSOR" "1")
(setenv "NO_BINPLACE" "TRUE")
(setenv "NEW_CRTS" "1")
(setenv "CRT_INC_PATH" (concat basedir "\\inc\\crt"))
(setenv "ATL_INC_PATH" (concat basedir "\\inc"))
(setenv "ATL_INC_ROOT" (concat basedir "\\inc"))
(setenv "MFC_INC_PATH" (concat basedir "\\inc\\mfc42"))
(setenv "SDK_INC_PATH" (concat basedir "\\inc\\api"))
(setenv "DDK_INC_PATH" (concat basedir "\\inc\\ddk"))
(setenv "WDM_INC_PATH" (concat basedir "\\inc\\ddk"))
(setenv "OAK_INC_PATH" (concat basedir "\\inc\\api"))
(setenv "IFSKIT_INC_PATH" (concat basedir "\\inc\\ddk"))
(setenv "HALKIT_INC_PATH" (concat basedir "\\inc\\ddk"))
(setenv "DRIVER_INC_PATH" (concat basedir "\\inc\\ddk"))
(setenv "SDK_LIB_DEST" (concat basedir "\\lib\\" (getenv "_ddkspec")))
(setenv "DDK_LIB_DEST" (getenv "SDK_LIB_DEST"))
(setenv "IFSKIT_LIB_DEST" (getenv "SDK_LIB_DEST"))
(setenv "SDK_LIB_PATH" (concat basedir "\\lib\\" (getenv "_ddkspec") "\\*"))
(setenv "DDK_LIB_PATH" (getenv "SDK_LIB_PATH"))
(setenv "HALKIT_LIB_PATH" (getenv "SDK_LIB_PATH"))
(setenv "IFSKIT_LIB_PATH" (getenv "SDK_LIB_PATH"))
(setenv "CRT_LIB_PATH" (concat basedir "\\lib\\crt\\*"))
(setenv "ATL_LIB_PATH" (concat basedir "\\lib\\atl\\*"))
(setenv "MFC_LIB_PATH" (concat basedir "\\lib\\mfc\\*"))

(getenv "_ddkspec")

;;if exist %BASEDIR%\bin\setwdf.bat call %BASEDIR%\bin\setwdf.bat  //FIXME

(setenv "LINK_LIB_IGNORE" "4198")
(setenv "RCNOFONTMAP" "1")
(setenv "USERNAME" "WinDDK")

;;(setq path (concat "c:\\windows\\system32;"
;;				   "h:/cygwin/bin;"
;;					 path))

(setenv "PATH" path)

;;cd /d %BASEDIR%               //FIXME
;;doskey /macrofile=%BASEDIR%\bin\generic.mac
;;doskey /macrofile=%BASEDIR%\bin\ddktree.mac

);;function end

(defun wwn-smart-compile ()
  "Simply compile your file according to the file type."
  (interactive)
  (save-some-buffers t)
  (let
      ((compile-command nil)
       (alist
        (list '("\\.c$" .  "build.exe")
              '("\\.cc$" . "g++")
              '("\\.cpp$" . "g++"))))

    (while (not (null alist))
      (if (string-match (caar alist) (buffer-file-name))
          (setq compile-command
                (concat (cdar alist) " " (buffer-file-name))))
	  (setq alist (cdr alist)))

    (if (null compile-command)
		(setq compile-command
			  (read-from-minibuffer "Compile command: ")))
	
    (compile compile-command))
)

(defun wwn-cscope-database()
  (interactive)
  (save-some-buffers t)
  (let
	  ((compile-command nil)
	   (alist
		(list '("\\.c$" .  "c:\\makedirlist.bat")
			  '("\\.cc$" . "g++")
			  '("\\.cpp$" . "g++"))))
	(while (not (null alist))
	  (if (string-match (caar alist) (buffer-file-name))
          (setq compile-command
				(concat (cdar alist) " " (buffer-file-name))))
	  (setq alist (cdr alist)))

	(if (null compile-command)
		(setq compile-command
			  (read-from-minibuffer "Compile command: ")))
	
	(compile compile-command))
)

(provide 'wwn)

(global-set-key [C-f5] 'compile)
(global-set-key [f5] 'wwn-smart-compile)

(define-derived-mode ddk-mode c-mode "DDK"
  "Windows DDK6000 Build Env"
  )

(easy-menu-define ddk-menu ddk-mode-map "My own menu"
  '("DDK"
    ["Build" wwn-smart-compile]
    
	("Windows 2000"
     ["X86 checked build" (wwn-setenv "w2k" "I386" "chk")]
	 ["X86 free build" (wwn-setenv "w2k" "I386" "free")])
	
	("Windows Server 2003"
     ["IA64 checked build" (wwn-setenv "WNet" "IA64" "chk")]
	 ["IA64 free build" (wwn-setenv "WNet" "IA64" "chk")]
	 ["X86 checked build" (wwn-setenv "WNet" "I386" "chk")]
	 ["X86 free build" (wwn-setenv "WNet" "I386" "free")]
	 ["AMD64 checked build" (wwn-setenv "WNet" "AMD64" "chk")]
	 ["AMD64 free build" (wwn-setenv "WNet" "AMD64" "free")]) 
	
	("Windows Vista and Longhorn"
     ["Longhorn IA64 checked build" (wwn-setenv "Wlh" "IA64" "chk")]
	 ["Longhorn IA64 free build" (wwn-setenv "Wlh" "IA64" "free")]
	 ["Vista and Longhorn X86 checked build" (wwn-setenv "Wlh" "I386" "chk")]
	 ["Vista and Longhorn X86 free build" (wwn-setenv "Wlh" "I386" "free")]
	 ["Vista and Longhorn AMD64 checked build" (wwn-setenv "Wlh" "AMD64" "chk")]
	 ["Vista and Longhorn AMD64 free build" (wwn-setenv "Wlh" "AMD64" "free")] )

	("Windows XP"
	 ["X86 checked build" (wwn-setenv "WXP" "I386" "chk")]
	 ["X86 free build" (wwn-setenv "WXP" "I386" "free")] ) ))

;;(defun ddkenv-c-style-fix ()
;;  (ddk-mode))

;;(add-hook 'c-mode-hook 'ddkenv-c-style-fix)